#include "imageutil.h"

QImage ImageUtil::yuyvArr2QImage(const uchar *data, int width, int height)
{
    QImage image(width, height, QImage::Format_RGB32);

    for (int y = 0; y < height; ++y) {
        // 获取当前行的YUV数据指针
        const uchar *yuyvLine = data + y * width * 2; // 每行占用 width*2 字节
        QRgb *rgbLine = reinterpret_cast<QRgb*>(image.scanLine(y));

        // 每4字节处理两个像素（YUYV格式）
        for (int x = 0; x < width; x += 2) {
            // 提取YUV分量
            uchar Y0 = yuyvLine[0];  // 第一个像素的Y
            uchar U  = yuyvLine[1];  // 共用U分量
            uchar Y1 = yuyvLine[2];  // 第二个像素的Y
            uchar V  = yuyvLine[3];  // 共用V分量
            yuyvLine += 4;           // 移动到下一个YUYV块

            // YUV转RGB（BT.601标准，TV范围）
            auto convert = [](uchar Y, uchar U, uchar V) -> QRgb {
                // 调整YUV到有效范围
                int y = qMax((int)Y, 16) - 16;  // Y范围: 16-235 → 0-219
                int u = U - 128;           // U范围: 0-255 → -128-127
                int v = V - 128;           // V范围: 0-255 → -128-127

                // 整数运算（使用64位防溢出）
                int r = (298 * y + 409 * v + 128) >> 8;
                int g = (298 * y - 100 * u - 208 * v + 128) >> 8;
                int b = (298 * y + 516 * u + 128) >> 8;

                // 限制到0-255范围
                r = qBound(0, r, 255);
                g = qBound(0, g, 255);
                b = qBound(0, b, 255);

                return qRgb(r, g, b);
            };

            // 转换两个像素
            rgbLine[x]     = convert(Y0, U, V);
            rgbLine[x + 1] = convert(Y1, U, V);
        }
    }
    return image;
}
